package com.cy.prototype;


/**
 * <br>@class: PrototypeTest
 * <br>@description: 原型
 * <br>@author: cy
 * <br>@date: 2020-03-28 20:50:18
 * <br>@version: 1.0
 * <br>
 * <br>@since: (版本) 作者 时间 注释
 */
public class PrototypeTest {
    //原形实例指定创建对象的种类，并且通过拷贝这些原形创建新的对象；
    //关键点：实现 Cloneable接口，重写 Object#clone方法
    //浅拷贝/深拷贝
    //序列号机制实现深拷贝
    public static void main(String[] args) throws CloneNotSupportedException {
        //新建对象
        AgentSmithPrototype a1 = new AgentSmithPrototype("斯密斯", 3);
        a1.setAgentPrototype(new AgentPrototype("1001"));
        a1.setATK(100);
        a1.setDEF(50);
        //拷贝对象
        AgentSmithPrototype a2 = a1.clone();
        //对比
        System.out.println(a1);
        System.out.println(a2);
        //原形改变后
        System.out.println("原形改变后");
        a1.setLevel(a1.getLevel()+1);
        a1.setATK(100+3);
        a1.getAgentPrototype().setAgent_id("1005");
        //对比
        System.out.println(a1);
        System.out.println(a2);
        //浅拷贝，基础数据类型与 包装类，原型改变后 克隆体不随之改变,对象型，原型改变后随之改变

        //深拷贝，基础数据类型与 包装类，原型改变后 克隆体不随之改变,对象型，原型改变后不随之改变
    }

}
//原型类中类
class AgentPrototype implements Cloneable{
    public AgentPrototype(String agent_id) {
        this.agent_id = agent_id;
    }
    private String agent_id;
    public String getAgent_id() {
        return agent_id;
    }
    public void setAgent_id(String agent_id) {
        this.agent_id = agent_id;
    }

    @Override
    protected AgentPrototype clone() throws CloneNotSupportedException {
        return (AgentPrototype)super.clone();
    }
}
//原型类
class AgentSmithPrototype implements Cloneable {
    private String name;
    private int level;
    //
    private Integer ATK;
    private Integer DEF;
    //
    private AgentPrototype agentPrototype;

    public AgentSmithPrototype(String name, int level) {
        this.name = name;
        this.level = level;
    }
    public void setAgentPrototype(AgentPrototype agentPrototype) {
        this.agentPrototype = agentPrototype;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setLevel(int level) {
        this.level = level;
    }
    public String getName() {
        return name;
    }
    public int getLevel() {
        return level;
    }
    public Integer getATK() {
        return ATK;
    }
    public void setATK(Integer ATK) {
        this.ATK = ATK;
    }
    public Integer getDEF() {
        return DEF;
    }
    public void setDEF(Integer DEF) {
        this.DEF = DEF;
    }
    public AgentPrototype getAgentPrototype() {
        return agentPrototype;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("AgentSmithPrototype hashcode="+this.hashCode()+"{");
        sb.append("name='").append(name).append('\'');
        sb.append(", level=").append(level);
        sb.append(", ATK=").append(ATK);
        sb.append(", DEF=").append(DEF);
        sb.append(", AID=").append(agentPrototype.getAgent_id());
        sb.append(", AID hashcode=").append(agentPrototype.hashCode());
        sb.append('}');
        return sb.toString();
    }

    @Override
    protected AgentSmithPrototype clone() throws CloneNotSupportedException {
        AgentSmithPrototype a = (AgentSmithPrototype) super.clone();
        //深拷贝
        a.setAgentPrototype(agentPrototype.clone());//此行保证深拷贝
        return a;
    }
}
